﻿using System;
using System.Net.Sockets;
using System.IO;
using Communication.Packets;
using Communication.Tcp;
using ConnectServer.Protocol;
using Utilities;

namespace ConnectServer.Management
{
    /// <summary>
    /// Represents ConnectServer's user.
    /// </summary>
    class User
    {
        #region Ctor
        public User(TcpClient client, Server invoker)
        {
            this.m_client = client;
            this.m_invoker = invoker;
        }
        #endregion

        #region Methods

        /// <summary>
        /// Sends a packet to the user.
        /// </summary>
        /// <param name="packet">Packet to send</param>
        public void Send(Packet packet)
        {
            BufferedStream buffer = new BufferedStream(new MemoryStream());
            packet.Serialize(buffer);
            this.m_invoker.SendToClient(this.m_client, buffer);
        }

        /// <summary>
        /// Logs an Information message with the IP of the user.
        /// </summary>
        /// <param name="format"></param>
        /// <param name="args"></param>
        public void Log(string format, params object[] args)
        {
            string header = string.Format("[{0}] ", this.m_client.Client.RemoteEndPoint);
            Logger.Instance.Log(header + format, args);
        }

        /// <summary>
        /// Logs an Error message with the IP of the user.
        /// </summary>
        /// <param name="format"></param>
        /// <param name="args"></param>
        public void LogError(string format, params object[] args)
        {
            string header = string.Format("[{0}] ", this.m_client.Client.RemoteEndPoint);
            Logger.Instance.LogError(header + format, args);
        }
        #endregion

        #region Packet Handling
        private void handleServerListRecv()
        {
            ServerListPacket packet = new ServerListPacket();
            this.Send(packet);
            this.Log("Server list sent.");
        }

        private void handleServerInfoRecv(BufferedStream buffer)
        {
            ServerInfoPacket packet = new ServerInfoPacket(buffer);
            this.Send(packet);
            this.Log("Server selected.");
        }

        public void HandlePacket(Type packetType, BufferedStream buffer)
        {

            switch (packetType.Name)
            {
                case "ServerListPacket":
                    handleServerListRecv();
                    break;
                case "ServerInfoPacket":
                    handleServerInfoRecv(buffer);
                    break;
            }
        }
        #endregion

        #region Properties
        public TcpClient Client 
        { 
            get { return this.m_client; } 
        }
        #endregion

        #region Fields
        private Server m_invoker;
        private TcpClient m_client;
        #endregion
    }
}
